home *** CD-ROM | disk | FTP | other *** search
/ Beginning Mac Programming / Beginning Mac Programming.bin / Open Me for REALbasic 3 / REALbasic 3.2 / Example Projects / Techniques / Examples by Thomas Tempelmann / TT's FileMgr-Plugin / Source Code (CW Pro 3) / Plugin Source.cpp < prev   
Text File  |  1999-07-03  |  8KB  |  303 lines

  1. /*
  2.  * REALbasic-Plugin that provides some useful Volume- and File-related functions.
  3.  *
  4.  * MacOS-only! (not useful under Windows or Java)
  5.  * The enclosed project file was created using CodeWarrior Pro 3.
  6.  *
  7.  * This code is freeware, you may use and extend it as you like.
  8.  * Created March 8, 99 by Thomas Tempelmann.
  9.  * More RB-related stuff can be found here: <http://www.tempel.org/rb>
  10.  *
  11.  * Revision history
  12.  * ----------------
  13.  *  March 14, 99
  14.  *    Added VolResolveID()
  15.  *  March 26, 99
  16.  *    Added the methods SetFileFlags, Set/GetFolderFlags,
  17.  *        VolGetFolderItemID and VolResolveID.
  18.  *
  19.  * Enjoy and contribute!
  20.  */
  21.  
  22. #include <string.h>
  23. #include "rb_plugin.h"
  24.  
  25.  
  26. static long IsOnRemoteVolume (REALfolderItem volIn)
  27. // returns true if the specified file, folder or volume is not local but
  28. // on a File Sharing Server
  29. {
  30.     FSSpec fsSpec;
  31.     if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
  32.         IOParam pb;
  33.         GetVolParmsInfoBuffer buf;
  34.         pb.ioVRefNum = fsSpec.vRefNum;
  35.         pb.ioBuffer = (Ptr)&buf;
  36.         pb.ioReqCount = 14;
  37.         pb.ioNamePtr = nil;
  38.         if (PBHGetVolParmsSync ((HParmBlkPtr)&pb) == noErr && pb.ioActCount >= 14) {
  39.             if (buf.vMLocalHand != 0) return 1;
  40.         }
  41.     }
  42.     return 0;
  43. }
  44.  
  45. static long VolGetVRefNum (REALfolderItem volIn)
  46. // returns the (negative) volume reference number of a file, folder or volume
  47. {
  48.     FSSpec fsSpec;
  49.     if (REALFSSpecFromFolderItem (&fsSpec, volIn)) {
  50.         return fsSpec.vRefNum;
  51.     }
  52.     return 0;
  53. }
  54.  
  55. static REALfolderItem VolumeByVRefNum (long vRefNum)
  56. // returns a FolderItem that points to the root directory
  57. // of the specific volume reference number. nil is returned if
  58. // the volume reference number was not valid.
  59. {
  60.     FSSpec spec;
  61.     FSMakeFSSpec (vRefNum, fsRtDirID, "\p", &spec);
  62.     return REALFolderItemFromFSSpec (&spec);
  63. }
  64.  
  65. static long GetFileFlags (REALfolderItem f)
  66. // if the returned value is negative, an error has occured and the Attribute is not valid
  67. {
  68.     FSSpec fsSpec;
  69.     OSErr err = -1;
  70.     if (REALFSSpecFromFolderItem (&fsSpec, f)) {
  71.         FInfo fi;
  72.         err = FSpGetFInfo (&fsSpec, &fi);
  73.         if (!err) return fi.fdFlags;
  74.     }
  75.     return err;
  76. }
  77.  
  78. static long SetFileFlags (REALfolderItem f, long flags)
  79. // returns errors code
  80. {
  81.     FSSpec fsSpec;
  82.     OSErr err = -1;
  83.     if (REALFSSpecFromFolderItem (&fsSpec, f)) {
  84.         FInfo fi;
  85.         err = FSpGetFInfo (&fsSpec, &fi);
  86.         if (!err) {
  87.             fi.fdFlags = flags;
  88.             err = FSpSetFInfo (&fsSpec, &fi);
  89.         }
  90.     }
  91.     return err;
  92. }
  93.  
  94. static long GetFolderFlags (REALfolderItem f)
  95. // if the returned value is negative, an error has occured and the Attribute is not valid
  96. {
  97.     FSSpec fsSpec;
  98.     OSErr err = -1;
  99.     if (REALFSSpecFromFolderItem (&fsSpec, f)) {
  100.         CInfoPBRec pb;
  101.         pb.hFileInfo.ioNamePtr = fsSpec.name;
  102.         pb.hFileInfo.ioVRefNum = fsSpec.vRefNum;
  103.         pb.hFileInfo.ioDirID = fsSpec.parID;
  104.         pb.hFileInfo.ioFDirIndex = 0;
  105.         err = PBGetCatInfoSync (&pb);
  106.         if (!err) return pb.dirInfo.ioDrUsrWds.frFlags;
  107.     }
  108.     return err;
  109. }
  110.  
  111. static long SetFolderFlags (REALfolderItem f, long flags)
  112. // returns errors code
  113. {
  114.     FSSpec fsSpec;
  115.     OSErr err = -1;
  116.     if (REALFSSpecFromFolderItem (&fsSpec, f)) {
  117.         CInfoPBRec pb;
  118.         pb.hFileInfo.ioNamePtr = fsSpec.name;
  119.         pb.hFileInfo.ioVRefNum = fsSpec.vRefNum;
  120.         pb.hFileInfo.ioDirID = fsSpec.parID;
  121.         pb.hFileInfo.ioFDirIndex = 0;
  122.         err = PBGetCatInfoSync (&pb);
  123.         if (!err) {
  124.             pb.dirInfo.ioDrUsrWds.frFlags = flags;
  125.             pb.hFileInfo.ioDirID = fsSpec.parID;
  126.             err = PBSetCatInfoSync (&pb);
  127.         }
  128.     }
  129.     return err;
  130. }
  131.  
  132. static long GetFileAttribute (REALfolderItem f)
  133. // returns an Integer with the following bits to test for:
  134. //   0: locked
  135. //   2: rsrc fork open
  136. //   3: data fork open
  137. //   4: is directory
  138. //   7: file (one or both forks) is open
  139. // if the returned value is negative, an error has occured and the Attribute is not valid
  140. {
  141.     FSSpec fsSpec;
  142.     OSErr err = -1;
  143.     if (REALFSSpecFromFolderItem (&fsSpec, f)) {
  144.         HFileParam pb;
  145.         pb.ioVRefNum = fsSpec.vRefNum;
  146.         pb.ioFVersNum = 0;
  147.         pb.ioFDirIndex = 0;
  148.         pb.ioDirID = fsSpec.parID;
  149.         pb.ioNamePtr = fsSpec.name;
  150.         err = PBHGetFInfoSync ((HParmBlkPtr)&pb);
  151.         if (!err) return (long)(unsigned char) pb.ioFlAttrib;
  152.     }
  153.     return err;
  154. }
  155.  
  156. static long IsFileOpen (REALfolderItem f)
  157. // returns true if file is open, returns false if it is not open or not a file
  158. {
  159.     long l = GetFileAttribute (f);
  160.     return (l >= 0) && ((l & 0x8C) != 0);
  161. }
  162.  
  163. static long IsRsrcOpen (REALfolderItem f)
  164. // returns true if file's rsrc fork is open, returns false if it is not open or not a file
  165. {
  166.     long l = GetFileAttribute (f);
  167.     return (l >= 0) && ((l & 0x04) != 0);
  168. }
  169.  
  170. static REALfolderItem VolResolveIDByVRefNum (long vRefNum, long id)
  171. {
  172.     FSSpec spec;
  173.     OSErr err;
  174.     if (vRefNum >= 0 || id == 0) return nil;
  175.     err = FSMakeFSSpec (vRefNum, id, "\p", &spec);
  176.     if (err) {
  177.         FIDParam pb;
  178.         pb.ioVRefNum = vRefNum;
  179.         pb.ioNamePtr = spec.name;
  180.         pb.ioFileID = id;
  181.         err = PBResolveFileIDRefSync ((HParmBlkPtr)&pb);
  182.         if (err) {
  183.             return nil;
  184.         }
  185.         spec.vRefNum = vRefNum;
  186.         spec.parID = pb.ioSrcDirID;
  187.     }
  188.     return REALFolderItemFromFSSpec (&spec);
  189. }
  190.  
  191. static REALfolderItem VolResolveIDByFolderItem (REALfolderItem vol, long id)
  192. {
  193.     return VolResolveIDByVRefNum (VolGetVRefNum (vol), id);
  194. }
  195.  
  196. static long VolGetFolderItemID (REALfolderItem f, long createFileID)
  197. // returns 0 if an error occured
  198. {
  199.     FSSpec fsSpec;
  200.     OSErr err = -1;
  201.     if (REALFSSpecFromFolderItem (&fsSpec, f)) {
  202.         long theID;
  203.         Boolean isDir;
  204.         {
  205.             CInfoPBRec pb;
  206.             pb.hFileInfo.ioNamePtr = fsSpec.name;
  207.             pb.hFileInfo.ioVRefNum = fsSpec.vRefNum;
  208.             pb.hFileInfo.ioDirID = fsSpec.parID;
  209.             pb.hFileInfo.ioFDirIndex = 0;
  210.             err = PBGetCatInfoSync (&pb);
  211.             theID = pb.hFileInfo.ioDirID;    // a fileID/dirID is never 0
  212.             isDir = (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0;
  213.         }
  214.         if (!err) {
  215.             if (createFileID && !isDir) {
  216.                 FIDParam pb;
  217.                 pb.ioVRefNum = fsSpec.vRefNum;
  218.                 pb.ioNamePtr = fsSpec.name;
  219.                 pb.ioSrcDirID = fsSpec.parID;
  220.                 err = PBCreateFileIDRefSync ((HParmBlkPtr)&pb);
  221.                 if (err && err != fidExists) return 0;    // error, could not create the FileID
  222.                 theID = pb.ioFileID;
  223.             }
  224.             return theID;
  225.         }
  226.     }
  227.     return 0;
  228. }
  229.  
  230. static REALfolderItem myNewFolderItem (const FSSpec* spec)
  231. {
  232.     return REALFolderItemFromFSSpec (spec);
  233. }
  234.  
  235. static REALfolderItem NewFolderItem (long vRefNum, long parID, REALstring name)
  236. // returns nil if an error occured
  237. {
  238.     FSSpec spec;
  239.     FSMakeFSSpec(vRefNum, parID, REALPString(name), &spec);
  240.     return myNewFolderItem (&spec);
  241. }
  242.  
  243. typedef struct {
  244.     char    unknown[24];
  245.     long    size;
  246.     Ptr        dataPtr;
  247. } RBMemoryBlock;
  248.  
  249.  
  250. static REALfolderItem NewFolderItemFromFSSpecAsMemBlk (RBMemoryBlock* fsSpec)
  251. // returns nil if an error occured
  252. {
  253.     if (fsSpec == NULL) {
  254.         return nil;
  255.     }
  256.     return myNewFolderItem ((FSSpec*)fsSpec->dataPtr);
  257. }
  258.  
  259. REALexport pluginExports[] = {
  260.     { nil, IsOnRemoteVolume },
  261.     { nil, VolGetVRefNum },
  262.     { nil, VolumeByVRefNum },
  263.     { nil, GetFileFlags },
  264.     { nil, SetFileFlags },
  265.     { nil, GetFolderFlags },
  266.     { nil, SetFolderFlags },
  267.     { nil, GetFileAttribute },
  268.     { nil, IsFileOpen },
  269.     { nil, IsRsrcOpen },
  270.     { nil, VolResolveIDByVRefNum },
  271.     { nil, VolResolveIDByFolderItem },
  272.     { nil, VolGetFolderItemID },
  273.     { nil, NewFolderItem },
  274.     { nil, NewFolderItemFromFSSpecAsMemBlk },
  275. };
  276.  
  277. short pluginExportCode = sizeof(pluginExports) / sizeof(REALexport);
  278.  
  279. REALmethodDefinition methods[] = {
  280.     {0,    "IsOnRemoteVolume(fileOrFolder as FolderItem) as Boolean"},
  281.     {1,    "VolGetVRefNum(fileOrFolder as FolderItem) as Integer"},
  282.     {2,    "VolumeByVRefNum(vRefNum as Integer) as FolderItem"},
  283.     {3,    "GetFileFlags(file as FolderItem) as Integer"},
  284.     {4,    "SetFileFlags(file as FolderItem, flags as Integer) as Integer"},
  285.     {5,    "GetFolderFlags(folder as FolderItem) as Integer"},
  286.     {6,    "SetFolderFlags(folder as FolderItem, flags as Integer) as Integer"},
  287.     {7,    "GetFileAttribute(file as FolderItem) as Integer"},
  288.     {8,    "IsFileOpen(file as FolderItem) as Boolean"},
  289.     {9,    "IsResourceForkOpen(file as FolderItem) as Boolean"},
  290.     {10,"VolResolveID(vRefNum as Integer, id as Integer) as FolderItem"},
  291.     {11,"VolResolveID(vol as FolderItem, id as Integer) as FolderItem"},
  292.     {12,"VolGetFolderItemID(item as FolderItem, createFileIDs as Boolean) as Integer"},
  293.     {13,"NewFolderItem(vRefNum as Integer, parID as Integer, name as String) as FolderItem"},
  294.     {14,"NewFolderItemFromFSSpec(fsSpec as MemoryBlock) as FolderItem"},
  295. };
  296.  
  297. void PluginEntry (void)
  298. {
  299.     for (int i = 0; i < pluginExportCode; ++i) {
  300.         REALRegisterMethod (&methods[i]);
  301.     }
  302. }
  303.